package com.yjd.comm.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.util.ReflectionUtils;

import com.caucho.hessian.client.HessianProxyFactory;
import com.yjd.comm.rpm.RpmServiceKeyEnum;
import com.yjd.comm.util.FrameUtil;
import com.yjd.comm.util.SpringContextHolder;
import com.yjd.comm.util.StringUtil;
import com.yjd.comm.vo.Constant.PropertiesFileEnum;

/**
 * @ClassName: ServiceProxyHandle
 * @Description: service远程服务接口
 * @author ready likun_557@163.com
 * @date 2014-8-20 下午10:05:01
 */
public class ServiceRemoteProxyHandle extends
		InstantiationAwareBeanPostProcessorAdapter {

	/**
	 * 缓存远程服务对象
	 */
	private static Map<String, Object> serviceProxyMap = new HashMap<String, Object>();

	private static Logger logger = Logger
			.getLogger(ServiceRemoteProxyHandle.class);

	// bean初始化的时候调用，容器启动时
	public boolean postProcessAfterInstantiation(final Object bean,
			String beanName) throws BeansException {
		// 反射改变当前bean中的字段的值
		ReflectionUtils.doWithFields(bean.getClass(),
				new ReflectionUtils.FieldCallback() {
					public void doWith(Field field)
							throws IllegalArgumentException,
							IllegalAccessException {
						// 获取使用了@ServiceProxy注解的类
						ServiceRemoteProxy cfg = field
								.getAnnotation(ServiceRemoteProxy.class);
						if (cfg != null) {
							// 是否是静态变量
							if (Modifier.isStatic(field.getModifiers())) {
								throw new IllegalStateException(
										"@ServiceProxy annotation is not supported on static fields");
							}
							// 获取注解的value属性值
							String beanId = cfg.value().length() <= 0 ? field
									.getName() : cfg.value();
							ReflectionUtils.makeAccessible(field);
							Object target = null;
							try{
								/*String s = FrameUtil.json(SpringContextHolder.getApplicationContext().getBeanDefinitionNames(), true);
								System.out.println(s);*/
								target = SpringContextHolder.getBean(beanId);
								if(!field.getType().isInstance(target)){
									target = null;
								}
							}catch(Exception e){
//								logger.error(e.getMessage(), e);
							}
							if(target==null){
								String serviceUrl = FrameUtil.getResourceByFile(PropertiesFileEnum.RPM_SERVICE.getFilename(), cfg
										.serviceUrlResouceKey());
								if(StringUtil.isEmpty(serviceUrl) || serviceUrl.equals(cfg.serviceUrlResouceKey())){
									serviceUrl = FrameUtil.getConstResource(cfg.serviceUrlResouceKey());
								}
								if(StringUtil.isEmpty(serviceUrl) || serviceUrl.equals(cfg.serviceUrlResouceKey())){
									serviceUrl = RpmServiceKeyEnum.RPM_PUBLIC_KEY_E.getRpmServiceUrl();
								}
								if (StringUtil.isEmpty(serviceUrl)) {
									throw new IllegalStateException(
											"serviceUrl is empty in file const.properties");
								}
								target = getServiceProxy(field.getType(), serviceUrl
										+ "/" + beanId);
							}
							field.set(bean,target);
						}
					}
				});
		return true;
	}

	/**
	 * @Title: getBean
	 * @Description: 获取远程服务对象
	 * @param @param serviceClass 远程服务对象的接口的class
	 * @param @param remoteServiceUrl 远程服务对象的地址
	 * @param @return
	 * @param @throws Exception 设定文件
	 * @return T 返回远程服务对象
	 * @throws
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <T> T getServiceProxy(Class serviceClass,
			String remoteServiceUrl) {
		try {
			String key = serviceClass.getName() + "_" + remoteServiceUrl;
			if (serviceProxyMap.get(key) == null) {
				// 创建远程调用对象
				HessianProxyFactory factory = new HessianProxyFactory();
				factory.setOverloadEnabled(true);
				Object o = factory.create(serviceClass, remoteServiceUrl);
				serviceProxyMap.put(key, o);
			}
			return (T) serviceProxyMap.get(key);
		} catch (Exception e) {
			logger.error(remoteServiceUrl + " 远程对象不存在:" + e.getMessage(), e);
			throw new RuntimeException(remoteServiceUrl + " 远程对象不存在", e);
		}
	}
}